package com.jihox.abookpro.dao;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.util.Vector;

import com.jihox.abookpro.domain.Book;
import com.jihox.abookpro.domain.BookProject;
import com.jihox.abookpro.domain.BookTemplate;
import com.jihox.abookpro.domain.Caption;
import com.jihox.abookpro.domain.Color;
import com.jihox.abookpro.domain.Page;
import com.jihox.abookpro.domain.PagePicture;
import com.jihox.abookpro.uploader.MyZip;
import com.jihox.abookpro.util.MyMapperWrapper;
import com.jihox.abookpro.util.PictureUtil;
import com.thoughtworks.xstream.XStream;
import com.thoughtworks.xstream.io.xml.DomDriver;
import com.thoughtworks.xstream.mapper.MapperWrapper;

public class BookProjectDAO {

	public Vector<File> save(BookProject project, File file,String cacheDir) throws Exception {
		//HashMap<String, String> savedImageName = new HashMap<String, String>();
		XStream xstream = new XStream(new DomDriver()) {
			@Override
			protected MapperWrapper wrapMapper(MapperWrapper next) {
				return new MyMapperWrapper(next);
			}
		};
		
		Vector<File> files = new Vector<File>();
		
		int dpi = project.getBook().getProduct().getDpiOfPicture();
		int imageIndex =1;
		for (Page page : project.getBook().getPages()){
			if (page.getPictures() !=null){
				for (PagePicture pagePicture : page.getPictures()){
					if (!pagePicture.isClipart()){
						String imagePath = pagePicture.getImage().getPath();
						String newImageName = String.valueOf(imageIndex)+ getExtensionName(imagePath);
						imageIndex++;
					
						pagePicture.getImage().setPath(newImageName); 
						File outFile =new File(cacheDir,newImageName);
						PictureUtil.cropAndCompressImage(imagePath, outFile.getPath(),pagePicture, dpi);
						files.add(outFile);
					}
				}
			}
		}
		
		xstream.alias("BookProject", BookProject.class);
		xstream.useAttributeFor(BookProject.class, "xmlns");
		xstream.alias("BookTemplate", BookTemplate.class);
		xstream.alias("Page", Page.class);
		xstream.alias("PagePicture", PagePicture.class);
		xstream.alias("Caption", Caption.class);
		xstream.alias("Color", Color.class);
		xstream.addImplicitCollection(Book.class, "pages");
		xstream.addImplicitCollection(Page.class, "pictures",PagePicture.class);
		xstream.addImplicitCollection(Page.class, "captions",Caption.class);
		xstream.omitField(BookProject.class, "images");
		OutputStreamWriter write = null;
		FileOutputStream os = null;
		try {
			os = new FileOutputStream(file);
			write = new OutputStreamWriter(os, "UTF-8");
			xstream.toXML(project, os);
		} catch (Exception e) {
			throw e;
		} finally {
			try {
				if (write != null) {
					write.close();
				}
				if (os != null) {
					os.close();
				}
			} catch (IOException e) {
				e.printStackTrace();
			}

		}
		
		return files;
	}
	
	private String getExtensionName(String filename) {    
        if ((filename != null) && (filename.length() > 0)) {    
            int dot = filename.lastIndexOf('.');    
            if ((dot >-1) && (dot < (filename.length() - 1))) {    
                return filename.substring(dot);    
            }    
        }    
        return filename;    
    }    
	
	public void saveProject(BookProject project,String path) throws Exception {
		XStream xstream = new XStream();
		
		xstream.alias("bookProject", BookProject.class);
		xstream.alias("book", Book.class);
		xstream.alias("bookTemplate", BookTemplate.class);
		xstream.alias("page", Page.class);
		xstream.alias("pagePicture", PagePicture.class);
		xstream.alias("caption", Caption.class);
		xstream.alias("color", Color.class);
		xstream.addImplicitCollection(Book.class, "pages");
		xstream.addImplicitCollection(Page.class, "pictures",PagePicture.class);
		xstream.addImplicitCollection(Page.class, "captions",Caption.class);
		OutputStreamWriter write = null;
		FileOutputStream os = null;
		try {
			os = new FileOutputStream(path);
			write = new OutputStreamWriter(os, "UTF-8");
			xstream.toXML(project, os);
		} catch (Exception e) {
			throw e;
		} finally {
			try {
				if (write != null) {
					write.close();
				}
				if (os != null) {
					os.close();
				}
			} catch (IOException e) {
				e.printStackTrace();
			}

		}
	}
	
	public BookProject retrieveBookProject(String fileName)
			throws Exception {
		BookProject project = null;

		File file = new File(fileName);
		if (!file.exists()) {
			return project;
		}
		FileInputStream is = null;
		try {
			is = new FileInputStream(file);
			
			XStream xstream = new XStream();
			xstream.alias("BookProject", BookProject.class);
			xstream.alias("book", Book.class);
			xstream.alias("bookTemplate", BookTemplate.class);
			xstream.alias("page", Page.class);
			xstream.alias("pagePicture", PagePicture.class);
			xstream.alias("caption", Caption.class);
			xstream.alias("color", Color.class);
			xstream.addImplicitCollection(Book.class, "pages");
			xstream.addImplicitCollection(Page.class, "pictures",PagePicture.class);
			xstream.addImplicitCollection(Page.class, "captions",Caption.class);
			
			project = new BookProject();
			project = (BookProject) xstream.fromXML(is, project);

		} catch (Exception ex) {
			ex.printStackTrace();
		} finally {
			try {
				if (is != null) {
					is.close();
				}
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		return project;
	}
	
	public BookProject getBookProject(String fileName)
			throws Exception {
		BookProject project = null;

		File file = new File(fileName);
		if (!file.exists()) {
			return project;
		}
		FileInputStream is = null;
		try {
			is = new FileInputStream(file);
			new Book();
			XStream xstream = new XStream(new DomDriver()) {
				@Override
				protected MapperWrapper wrapMapper(MapperWrapper next) {
					return new MyMapperWrapper(next);
				}
			};
			xstream.alias("BookProject", BookProject.class);
			xstream.alias("book", Book.class);
			xstream.alias("Page", Page.class);
			xstream.alias("PagePicture", PagePicture.class);
			xstream.alias("Caption", Caption.class);
			xstream.alias("Color", Color.class);
			xstream.addImplicitCollection(Book.class, "pages");
			xstream.addImplicitCollection(Page.class, "pictures",PagePicture.class);
			xstream.addImplicitCollection(Page.class, "captions",Caption.class);
			
			project = new BookProject();
			project = (BookProject) xstream.fromXML(is, project);

		} catch (Exception ex) {
			ex.printStackTrace();
		} finally {
			try {
				if (is != null) {
					is.close();
				}
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		return project;
	}

	public void saveAndZip(BookProject project, File zipFile,String cacheDir) throws Exception {
		try {
			
			File dir = new File(cacheDir);
			
			if (!dir.exists()){
				dir.mkdirs();
			}
			File xmlFile = new File(zipFile.toString().replace("_original.zip", ".phb"));
			
			Vector<File> files =  save(project, xmlFile,cacheDir);
			files.add(xmlFile);
			
			MyZip.createZip(zipFile, files);
			if (xmlFile.exists()){
				xmlFile.delete();
			}
			
			if (dir.exists()){
				 File tempFiles[] = dir.listFiles(); 
			     for(int i=0;i<tempFiles.length;i++){ 
			    	 tempFiles[i].delete(); 
			     } 	
			     dir.delete();
			} 
			
		} catch (Exception e) {
			e.printStackTrace();
			throw e;
		}
	}

}
